﻿using System.Diagnostics;

namespace EveKillboard.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;
    using Core;
    using Core.Exceptions;
    using Data;

    [Authorize(Users = "Admin")]
    public class AdminController : LocalizedController
    {
        private const int MAX_COUNT = 100;
        private static TraceSource dapTraceSource = new TraceSource("DataAccessProvider");

        public ActionResult Index(string error = null)
        {
            if(!string.IsNullOrEmpty(error))
                ViewData["error"] = error;
            return View();
        }

        #region Alliances

        public PartialViewResult Alliances(int index = 0, string sort = null, string sortOrder = "asc")
        {
            IEnumerable<Alliance> alliances = null;

            using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                alliances = dap.FindAll<Alliance>(MAX_COUNT, MAX_COUNT * index, false).ToArray();

            if (!string.IsNullOrEmpty(sort))
            {
                var property = typeof(Alliance).GetProperty(sort);
                switch (property.PropertyType.Name)
                {
                    case "Nullable`1":
                        alliances = sortOrder == "asc" ? alliances.OrderBy(a => (int?)property.GetValue(a, null)) : alliances.OrderByDescending(a => (int?)property.GetValue(a, null));
                        break;
                    case "Int32":
                    case "Int16":
                        alliances = sortOrder == "asc" ? alliances.OrderBy(a => (int)property.GetValue(a, null)) : alliances.OrderByDescending(a => (int)property.GetValue(a, null));
                        break;
                    case "String":
                        alliances = sortOrder == "asc" ? alliances.OrderBy(a => (string)property.GetValue(a, null)) : alliances.OrderByDescending(a => (string)property.GetValue(a, null));
                        break;
                }
            }
            bool canGoPrevious = index > 0;
            bool canGoNext = alliances.Count() == MAX_COUNT;
            ViewData["previous"] = string.Format("'{0}?index={1}&sort={2}&sortOrder={3}'", Url.Action("Alliances", "Admin"), canGoPrevious ? index - 1 : 0, sort, sortOrder);
            ViewData["next"] = string.Format("'{0}?index={1}&sort={2}&sortOrder={3}'", Url.Action("Alliances", "Admin"), canGoNext ? index + 1 : 0, sort, sortOrder);
            ViewData["sortOrder"] = sortOrder;
            return PartialView("Alliances", alliances);
        }
            
        [HttpPost]
        public ActionResult DeleteAlliance(int id)
        {
            if (id > 0)
                try
                {
                    using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                        dap.Delete<Alliance>(a => a.Id == id);
                }
                catch (DataAccessException exp)
                {
                    return PartialView("Error", exp);
                }
            return Alliances();
        }
        [HttpPost]
        public ActionResult EditAlliance(Alliance alliance)
        {
            if (ModelState.IsValid)
            {
                using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                {
                    var org = dap.Find<Alliance>(a => a.Id == alliance.Id);
                    if (org != null && org.EveId != alliance.EveId)
                    {
                        org.EveId = alliance.EveId;
                        org.Updated = DateTime.UtcNow;
                        dap.Save(org);
                    }
                }
            }
            return RedirectToAction("Index");
        }
        #endregion

        #region Corporations
        public PartialViewResult Corporations(int index = 0, string sort = null, string sortOrder = "asc")
        {
            IEnumerable<Corporation> corps = null;
            using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
               corps = dap.FindAll<Corporation>(MAX_COUNT, MAX_COUNT * index, false).ToArray();

            if(!string.IsNullOrEmpty(sort))
            {
                var property = typeof(Corporation).GetProperty(sort);
                switch (property.PropertyType.Name)
                {
                    case "Alliance":
                        corps = sortOrder == "asc" ? corps.OrderBy(c => (Alliance)property.GetValue(c, null)) : corps.OrderByDescending(c => (Alliance)property.GetValue(c, null));
                        break;
                    case "Nullable`1":
                        corps = sortOrder == "asc" ? corps.OrderBy(c => (int?)property.GetValue(c, null)) : corps.OrderByDescending(c => (int?)property.GetValue(c, null));
                        break;
                    case "Int32":
                    case "Int16":
                        corps = sortOrder == "asc" ? corps.OrderBy(c => (int)property.GetValue(c, null)) : corps.OrderByDescending(c => (int)property.GetValue(c, null));
                        break;
                    case "String":
                        corps = sortOrder == "asc" ? corps.OrderBy(c => (string)property.GetValue(c, null)) : corps.OrderByDescending(c => (string)property.GetValue(c, null));
                        break;
                }
            }

            bool canGoPrevious = index > 0;
            bool canGoNext = corps.Count() == MAX_COUNT;
            ViewData["previous"] = string.Format("'{0}?index={1}&sort={2}&sortOrder={3}'", Url.Action("Corporations", "Admin"), canGoPrevious ? index - 1 : 0, sort, sortOrder);
            ViewData["next"] = string.Format("'{0}?index={1}&sort={2}&sortOrder={3}'", Url.Action("Corporations", "Admin"), canGoNext ? index + 1 : 0, sort, sortOrder);
            ViewData["sortOrder"] = sortOrder;
            return PartialView("Corporations", corps);
        }

        [HttpPost]
        public ActionResult DeleteCorporation(int id)
        {
            if(id > 0)
                try
                {
                    using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                        dap.Delete<Corporation>(c => c.Id == id);
                }
                catch (DataAccessException exp)
                {
                    return PartialView("Error", exp);
                }
            return Corporations();
        }

        [HttpPost]
        public ActionResult Edit(int id, int type)
        {
            using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                switch (type)
                {
                    case 1 : // Corporation
                        return PartialView("Corporation", dap.Find<Corporation>(c => c.Id == id));
                    case 2 : // Alliance
                        return PartialView("Alliance", dap.Find<Alliance>(a => a.Id == id));
                }

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult EditCorporation(Corporation corp)
        {
            if(ModelState.IsValid)
            {
                using (var dap = new DataAccessProvider() { Trace = dapTraceSource })
                {
                    var org = dap.Find<Corporation>(c => c.Id == corp.Id);
                    if (org != null && org.EveId != corp.EveId)
                    {
                        org.EveId = corp.EveId;
                        org.Updated = DateTime.UtcNow;
                        dap.Save(org);
                    }    
                }
            }
            return RedirectToAction("Index");
        }
        #endregion

        public ActionResult Items ()
        {
            //var items = _dap.FindAll<Item>(false);
            return RedirectToAction("Index");
        }
        public ActionResult Groups ()
        {
            //var groups = _dap.FindAll<ItemGroup>(false);
            return RedirectToAction("Index");
        }
        public ActionResult Categories()
        {
            //var categories = _dap.FindAll<ItemGroupCategory>(false);
            return RedirectToAction("Index");
        }
        public ActionResult ItemPrices()
        {
            //var prices = _dap.FindAll<ItemValue>(false);
            return RedirectToAction("Index");
        }
        public ActionResult ShipSlots()
        {
            //var slots = _dap.FindAll<ShipSlot>(false);
            return RedirectToAction("Index");
        }
    }
}
